﻿#ifndef _UUID_VERIFY_H_H
#define	_UUID_VERIFY_H_H

#include <stdint.h>
#include <pincfg.h>
#include <dataproc.h>
#include <swap.h>
#include "dataproc.h"

#ifdef	__cplusplus
extern "C" {
#endif

/*******************************************************************************
* @brief 分组为4字的单元，即每组16字节
********************************************************************************
* 操作应保持在 alloc 和 free 之间
* enc_gen 和 dec_gen 为独立运算，结果暂存des_out;
* enc_gen 取元数据区数据进行加密	- 加密
* dec_gen 取加密区数据进行解密		- 解密
* rom_val_get 前要先调用对应的 rom_addr_make
* app 执行完 jiamihandle后应擦除该函数。然后填充返回指令
*******************************************************************************/
#define UIDVF_FUN_ADDR		0x08004000UL	// 	加密函数地址
#define UIDVF_UUID_ID		0x1FFFF7E8UL	// 	UUID地址
#define UIDVF_ENC_ADDR		0x0807F000UL	// 	加密数据地址		扇区对齐
#define UIDVF_SRC_ADDR		0x08002000UL	//	元数据地址			字对齐	
#define UIDVF_CODE_LEN		1024			//	密码本长度，字节数
#define UIDVF_BLOCK_SIZE	16				//	单元尺寸

/*******************************************************************************
* @brief	数据结构
*******************************************************************************/
typedef struct
{
	uint32_t addr;
	uint32_t key[4];
	uint32_t out[4];
} uidvf_ctr_type;

/*******************************************************************************
* @brief	过程控制
*******************************************************************************/
#define uidvf_check_alloc()		uidvf_ctr_type uidvf; uidvf.addr=0

// 键值获取
#define	uidvf_key_set(gp)											\
	uidvf.key[0] = inpw(uidvf.addr) * (gp + 11);					\
	uidvf.key[0] +=  inpw(uidvf.addr + 4) * 13;						\
	uidvf.key[1] = inpw(uidvf.addr) * (gp + 17);					\
	uidvf.key[1] +=  inpw(uidvf.addr + 8) * 19;						\
	uidvf.key[2] = inpw(uidvf.addr) * (gp + 23);					\
	uidvf.key[2] +=  inpw(uidvf.addr + 4) * 31;						\
	uidvf.key[3] = inpw(uidvf.addr) * (gp + 41);					\
	uidvf.key[3] +=  inpw(uidvf.addr + 8) * 47;						\
	swap_bit_map_u8(&uidvf.key[0], &uidvf.key[0]);					\
	swap_bit_map_u8(&uidvf.key[2], &uidvf.key[2]);							

// 获取指定分组的加密值，结果暂存 uidvf.out	
#define uidvf_enc_gen(gp)											\
	uidvf.addr = code_set_ub(uidvf.addr, byte_ub(UIDVF_UUID_ID));	\
	uidvf.addr = code_set_lb(uidvf.addr, byte_lb(UIDVF_UUID_ID));	\
	uidvf.addr = code_set_mb(uidvf.addr, byte_mb(UIDVF_UUID_ID));	\
	uidvf.addr = code_set_hb(uidvf.addr, byte_hb(UIDVF_UUID_ID));	\
	uidvf_key_set(gp)												\
	uidvf.addr = code_set_lb(uidvf.addr, byte_lb(UIDVF_SRC_ADDR));	\
	uidvf.addr = code_set_hb(uidvf.addr, byte_hb(UIDVF_SRC_ADDR));	\
	uidvf.addr = code_set_mb(uidvf.addr, byte_mb(UIDVF_SRC_ADDR));	\
	uidvf.addr = code_set_ub(uidvf.addr, byte_ub(UIDVF_SRC_ADDR));	\
	uidvf.addr += gp * UIDVF_BLOCK_SIZE;							\
	map_add_u32((void *)uidvf.addr, uidvf.key, uidvf.out, UIDVF_BLOCK_SIZE/4);


// 获取指定分组的解密值，结果暂存 uidvf.out
#define uidvf_dec_gen(gp)											\
	uidvf.addr = code_set_hb(uidvf.addr, byte_hb(UIDVF_UUID_ID));	\
	uidvf.addr = code_set_mb(uidvf.addr, byte_mb(UIDVF_UUID_ID));	\
	uidvf.addr = code_set_ub(uidvf.addr, byte_ub(UIDVF_UUID_ID));	\
	uidvf.addr = code_set_lb(uidvf.addr, byte_lb(UIDVF_UUID_ID));	\
	uidvf_key_set(gp)												\
	uidvf.addr = code_set_mb(uidvf.addr, byte_mb(UIDVF_ENC_ADDR));	\
	uidvf.addr = code_set_hb(uidvf.addr, byte_hb(UIDVF_ENC_ADDR));	\
	uidvf.addr = code_set_lb(uidvf.addr, byte_lb(UIDVF_ENC_ADDR));	\
	uidvf.addr = code_set_ub(uidvf.addr, byte_ub(UIDVF_ENC_ADDR));	\
	uidvf.addr += gp * UIDVF_BLOCK_SIZE;							\
	map_sub_u32((void *)uidvf.addr, uidvf.key, uidvf.out, UIDVF_BLOCK_SIZE/4);

	
// 制作加密区指定分组-元素的地址
#define uidvf_enc_rom_addr_make(gp, coil)							\
	uidvf.addr = code_set_hb(uidvf.addr, byte_hb(UIDVF_ENC_ADDR));	\
	uidvf.addr = code_set_lb(uidvf.addr, byte_lb(UIDVF_ENC_ADDR));	\
	uidvf.addr = code_set_mb(uidvf.addr, byte_mb(UIDVF_ENC_ADDR));	\
	uidvf.addr = code_set_ub(uidvf.addr, byte_ub(UIDVF_ENC_ADDR));	\
	uidvf.addr += gp * UIDVF_BLOCK_SIZE;	uidvf.addr += coil * 4;
		
// 制作元数据区指定分组-元素的地址
#define uidvf_src_rom_addr_make(gp, coil)							\
	uidvf.addr = code_set_lb(uidvf.addr, byte_lb(UIDVF_SRC_ADDR));	\
	uidvf.addr = code_set_mb(uidvf.addr, byte_mb(UIDVF_SRC_ADDR));	\
	uidvf.addr = code_set_ub(uidvf.addr, byte_ub(UIDVF_SRC_ADDR));	\
	uidvf.addr = code_set_hb(uidvf.addr, byte_hb(UIDVF_SRC_ADDR));	\
	uidvf.addr += gp * UIDVF_BLOCK_SIZE;	uidvf.addr += coil * 4;
		
#define uidvf_rom_val_get()	inpw(uidvf.addr)
		
// 清除堆栈内存数据
#define uidvf_free() memset(&uidvf, 0, sizeof(uidvf));
	
// 加密接口
void uidvf_handle(void);

#ifdef	__cplusplus
}
#endif

#endif	/* _UUID_VERIFY_H_H */
